home *** CD-ROM | disk | FTP | other *** search
/ NetNews Offline 2 / NetNews Offline Volume 2.iso / news / comp / lang / c-part2 / 15763 < prev    next >
Encoding:
Text File  |  1996-08-05  |  2.0 KB  |  91 lines

  1. Path: mayne.ugrad.cs.ubc.ca!not-for-mail
  2. From: c2a192@ugrad.cs.ubc.ca (Kazimir Kylheku)
  3. Newsgroups: comp.lang.c
  4. Subject: Re: Reusable and Generic Functions
  5. Date: 21 Apr 1996 10:56:56 -0700
  6. Organization: Computer Science, University of B.C., Vancouver, B.C., Canada
  7. Message-ID: <4ldst8INNlub@mayne.ugrad.cs.ubc.ca>
  8. References: <4la9k2$76o@wormer.fn.net>
  9. NNTP-Posting-Host: mayne.ugrad.cs.ubc.ca
  10.  
  11. In article <4la9k2$76o@wormer.fn.net>,
  12. Rusty Meathook <withheld@keepitpublic.com> wrote:
  13. >Suppose a guy has two linked list structures, such as:
  14. >
  15. >/* Untested code based on previously written tested code :) */
  16. >
  17. >typedef struct foo_tag
  18. >{
  19. >    int data;
  20. >    struct foo_tag *next;
  21. >} FOO;
  22. >
  23. >typedef struct bar_tag
  24. >{
  25. >    float data;
  26. >    struct bar_tag *next;
  27. >} BAR;
  28. >
  29. >/* */
  30. >
  31. >Is there a simple way to handle operations on both of those lists
  32. >using the same set of functions?  Say for adding links we have this
  33. >function:
  34.  
  35. Yes, but not in this manner. The proper C way of doing that would be to define
  36. a single list type item like this:
  37.  
  38. union generic {
  39.     double *d;
  40.     long l;
  41.     unsigned long u;
  42.     void *p;
  43. };
  44.  
  45. typedef struct listnode_tag {
  46.     union generic e;
  47.     struct listnode_tag *next;
  48. } listnode;
  49.  
  50. Now, you can store a pointer as listnode.e.p, a double as listnode.e.d and so
  51. forth.
  52.  
  53.  
  54. >/* Untested code based on previously written tested code :) */
  55. >
  56. >FOO *sllist_add(FOO *next, int data)
  57. >{
  58. >    FOO *temp;
  59.  
  60.  
  61. This would be written as:
  62.  
  63. listnode *sllist_add(listnode *next, union generic data)
  64.  
  65. {
  66.     /* ... */
  67.  
  68.     temp->data = data;    /* struct/union assignment    */
  69.  
  70.     return temp;
  71. }
  72.  
  73.  
  74. What do you think? The above is not super slick, but you could define
  75. ``alternate access'' functions to complement it:
  76.  
  77. listnode *sllist_add_ptr(listnode *next, void *ptr)
  78.  
  79. {
  80.     union generic data;
  81.  
  82.     data.e.p = ptr;
  83.  
  84.     /* ... and so forth     */
  85. }
  86.  
  87. It's up to the client code module to implement a discipline which will prevent
  88. it from storing an item as one type, and referencing it later as another type.
  89. A good rule of thumb would be to not store more than one type into any one
  90. distinct list.
  91.